package com.yahoo.labs.snow.solver;

import it.unimi.dsi.fastutil.ints.IntOpenHashSet;

import java.util.Random;

import cern.colt.list.DoubleArrayList;

import com.yahoo.labs.snow.ProblemInstance;
import com.yahoo.labs.snow.Snowflake;
import com.yahoo.labs.snow.util.MathUtils;

/**
 * Similar to {@link RandomBOBOSolver} but accepts only candidates that have a minimum sum of intra compat.
 * 
 * @author chato
 *
 */
public class RandomBOBOSolver extends RandomSOBOSolver {

	final int INITIAL_TRIALS_FOR_MU = 5;

	final double mu;

	public RandomBOBOSolver(ProblemInstance problem) {
		super(problem);
		mu = chooseMu();
		Solver.logger.info( "Mu (minimum sum of intra compatibility) initialized as " + mu);
	}

	/**
	 * Does {@link #INITIAL_TRIALS_FOR_MU} trials and picks the median sum intra compat of those as {@link #mu}.
	 * 
	 * @return
	 */
	private double chooseMu() {
		// Use our own random number generator
		Random muRandom = new Random(1);
		DoubleArrayList list = new DoubleArrayList(INITIAL_TRIALS_FOR_MU);
		IntOpenHashSet allIds = new IntOpenHashSet(problem.getIds());

		for (int i = 0; i < INITIAL_TRIALS_FOR_MU; i++) {
			int pivot = randomNode(muRandom);
			list.add(pickFlake(pivot, allIds).getSumIntraCompat());
		}

		return MathUtils.median(list);
	}

	@Override
	boolean candidateAcceptable(Snowflake candidate) {
		return (candidate.getSumIntraCompat() >= mu);
	}
}
